﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;

namespace StreetSmartAdmin
{

    public class UserInput
    {
        public string FuelType { get; set; }
        public string OrgType { get; set; }
        public string PostCode { get; set; }
        public string PlanType { get; set; }
        public string BillType { get; set; }
        public int DaysOnBill { get; set; }
        public int PeakUsage { get; set; }
        public int ShoulderUsage { get; set; }
        public int OffPeakUsage { get; set; }
        public int Green { get; set; }
        public double Bill { get; set; }

    }

    public class RatesQuery
    {
        public string FuelType { get; set; }
        public string State { get; set; }
        public string Provider { get; set; }
        public string PlanType { get; set; }
        public string RatesApply { get; set; }
        public string OrgType { get; set; }
    }

    public class DiscountResult
    {
        public string State { get; set; }
        public string ElectricityZone { get; set; }
        public double PreGST_Discount_RESI { get; set; }
        public double PostGST_Discount_RESI { get; set; }
        public string Rebate_RESI { get; set; }
        public string ProductCode_RESI { get; set; }
        public double PreGST_Discount_SME { get; set; }
        public double PostGST_Discount_SME { get; set; }
        public string Rebate_SME { get; set; }
        public string ProductCode_SME { get; set; }
    }

    public class RatesResult
    {
        public double Peak1 { get; set; }
        public double Peak1Threshold { get; set; }
        public double Peak2 { get; set; }
        public double Peak2Threshold { get; set; }
        public double Peak3 { get; set; }
        public double Peak3Threshold { get; set; }
        public double Peak4 { get; set; }
        public double Peak4Threshold { get; set; }
        public double Peak5 { get; set; }
        public double OffPeak1 { get; set; }
        public double OffPeak1Threshold { get; set; }
        public double OffPeak2 { get; set; }
        public double OffPeak2Threshold { get; set; }
        public double OffPeak3 { get; set; }
        public double OffPeak3Threshold { get; set; }
        public double OffPeak4 { get; set; }
        public double OffPeak4Threshold { get; set; }
        public double OffPeak5 { get; set; }
        public double Shoulder { get; set; }
        public double SupplyCharge { get; set; }
        public double AdditionalCharge { get; set; }
        public string Code { get; set; }
        public string Tariff { get; set; }
    }



    public class Output
    {
        public double PeakCharge { get; set; }
        public double OffPeakCharge { get; set; }
        public double ShoulderCharge { get; set; }
        public double SupplyCharge { get; set; }
        public double AdditionalCharge { get; set; }
        public double GreenCharge { get; set; }
        public double OurPrice { get; set; }
        public double OurPricePerYear { get; set; }
        public double SavePerBill { get; set; }
        public double SavePerYear { get; set; }

    }


    public partial class RatesCalculator : System.Web.UI.Page
    {
        static System.Configuration.ConnectionStringSettings connString = System.Configuration.ConfigurationManager.ConnectionStrings["SQLServer2005DBConnectionString"];
        static string connectionString = connString.ConnectionString;

        protected void Page_Load(object sender, EventArgs e)
        {
            ((Label)Header.FindControl("lblUser")).Text = (String)Session["UserName"];
            
        }



        protected void btnCal_Click(object sender, EventArgs e)
        {
            

            UserInput input = new UserInput();
            input.FuelType = FuelType.SelectedValue;
            input.OrgType = OrgType.SelectedValue;
            input.PostCode = SelPostcode.SelectedValue;
            input.PlanType = Plan.SelectedValue;

            input.DaysOnBill = Int32.Parse(DaysOnBill.Text);
            input.PeakUsage = Int32.Parse(PeakUsage.Text);
            input.ShoulderUsage = Int32.Parse(Shoulder.Text); 
            input.OffPeakUsage = Int32.Parse(OffPeakUsage.Text);
            input.Bill = Int32.Parse(Bill.Text);

            Output output = GetPrice(input);
            PeakCharge.Text = "$" + Convert.ToInt32(output.PeakCharge).ToString();
            OffPeakCharge.Text = "$" + Convert.ToInt32(output.OffPeakCharge).ToString();
            ShoulderCharge.Text = "$" + Convert.ToInt32(output.ShoulderCharge).ToString();
            SupplyCharge.Text = "$" + Convert.ToInt32(output.SupplyCharge).ToString();
            OurPrice.Text = "$" + Convert.ToInt32(output.OurPrice).ToString();
            OurPricePerYear.Text = "$" + Convert.ToInt32(output.OurPricePerYear).ToString();
            SavePerBill.Text = "$" + Convert.ToInt32(output.SavePerBill).ToString();
            SavePerYear.Text = "$" + Convert.ToInt32(output.SavePerYear).ToString();

        }



        protected Output GetPrice(UserInput input)
        {
            Output output;
            DiscountResult discount = GetDiscount(input.PostCode);
            RatesQuery query = new RatesQuery();
            query.FuelType = input.FuelType;
            query.OrgType = input.OrgType;
            query.PlanType = input.PlanType;         
            query.State = discount.State;
            query.RatesApply = "All-Year";
            if (input.FuelType == "Electricity")
                query.Provider = discount.ElectricityZone;
            else
            {
                query.Provider = GetGasZone(input.PostCode);
            }
            
            RatesResult rates = GetRates(query);
            //if(input.OrgType=="Residential")
              //  Price = discalcu(discount.PreGST_Discount_RESI,discount.PostGST_Discount_RESI,calcuCharge(elecrates, input));
            //else
              //  Price = discalcu(discount.PreGST_Discount_SME, discount.PostGST_Discount_SME, calcuCharge(elecrates, input));

            if (input.OrgType == "Residential")
                rates = calcudis(rates, discount.PreGST_Discount_RESI, discount.PostGST_Discount_RESI);
            else
                rates = calcudis(rates, discount.PreGST_Discount_SME, discount.PostGST_Discount_SME);

            output = calcuCharge(rates, input);
            return output;
        }

        protected RatesResult calcudis(RatesResult rate,double pre_dis, double post_dis)
        {
            rate.Peak1 = discalcu(pre_dis,post_dis,rate.Peak1);
            rate.Peak2 = discalcu(pre_dis, post_dis, rate.Peak2);
            rate.Peak3 = discalcu(pre_dis, post_dis, rate.Peak3);
            rate.Peak4 = discalcu(pre_dis, post_dis, rate.Peak2);
            rate.Peak5 = discalcu(pre_dis, post_dis, rate.Peak3);
            rate.OffPeak1 = discalcu(pre_dis, post_dis, rate.OffPeak1);
            rate.OffPeak2 = discalcu(pre_dis, post_dis, rate.OffPeak2);
            rate.OffPeak3 = discalcu(pre_dis, post_dis, rate.OffPeak3);
            rate.OffPeak4 = discalcu(pre_dis, post_dis, rate.OffPeak2);
            rate.OffPeak5 = discalcu(pre_dis, post_dis, rate.OffPeak3);
            rate.Shoulder = discalcu(pre_dis, post_dis, rate.Shoulder);
            rate.SupplyCharge = discalcu(pre_dis, post_dis, rate.SupplyCharge);
            rate.AdditionalCharge = discalcu(pre_dis, post_dis, rate.AdditionalCharge);
            return rate;
        }

        protected Output calcuCharge(RatesResult rate, UserInput input)
        {
            double PeakCharge = 0;
            double OffPeakCharge = 0;

            if (rate.Peak1Threshold == 0)
            {
                PeakCharge = input.PeakUsage * rate.Peak1;
            }
            else
            {
                if (input.PeakUsage <= rate.Peak1Threshold)
                {
                    PeakCharge = input.PeakUsage * rate.Peak1;
                }
                else 
                {
                    if (rate.Peak2Threshold == 0)
                    {
                        PeakCharge = rate.Peak1 * rate.Peak1Threshold + rate.Peak2 * (input.PeakUsage - rate.Peak1Threshold);
                    }
                    else
                    {
                        if (input.PeakUsage <= rate.Peak2Threshold)
                        {
                            PeakCharge = rate.Peak1 * rate.Peak1Threshold + rate.Peak2 * (input.PeakUsage - rate.Peak1Threshold);
                        }
                        else
                        {
                            if (rate.Peak3Threshold == 0)
                            {
                                PeakCharge = rate.Peak1 * rate.Peak1Threshold + rate.Peak2 * rate.Peak2Threshold + rate.Peak3 * (input.PeakUsage - rate.Peak1Threshold - rate.Peak2Threshold);
                            }
                            else
                            {
                                if (input.PeakUsage <= rate.Peak3Threshold)
                                {
                                    PeakCharge = rate.Peak1 * rate.Peak1Threshold + rate.Peak2 * rate.Peak2Threshold + rate.Peak3 * (input.PeakUsage - rate.Peak1Threshold - rate.Peak2Threshold);
                                }
                                else
                                {
                                    if (rate.Peak4Threshold == 0)
                                    {
                                        PeakCharge = rate.Peak1 * rate.Peak1Threshold + rate.Peak2 * rate.Peak2Threshold + rate.Peak3 * rate.Peak3Threshold + rate.Peak4 * (input.PeakUsage - rate.Peak1Threshold - rate.Peak2Threshold - rate.Peak3Threshold);
                                    }
                                    else
                                    {
                                        if (input.PeakUsage <= rate.Peak4Threshold)
                                        {
                                            PeakCharge = rate.Peak1 * rate.Peak1Threshold + rate.Peak2 * rate.Peak2Threshold + rate.Peak3 * rate.Peak3Threshold + rate.Peak4 * (input.PeakUsage - rate.Peak1Threshold - rate.Peak2Threshold - rate.Peak3Threshold);
                                        }
                                        else
                                        {
                                            PeakCharge = rate.Peak1 * rate.Peak1Threshold + rate.Peak2 * rate.Peak2Threshold + rate.Peak3 * rate.Peak3Threshold + rate.Peak4 * rate.Peak4Threshold + rate.Peak5 * (input.PeakUsage - rate.Peak1Threshold - rate.Peak2Threshold - rate.Peak3Threshold - rate.Peak4Threshold);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (rate.OffPeak1Threshold == 0)
            {
                OffPeakCharge = input.OffPeakUsage * rate.OffPeak1;
            }
            else
            {
                if (input.OffPeakUsage <= rate.OffPeak1Threshold)
                {
                    OffPeakCharge = input.OffPeakUsage * rate.OffPeak1;
                }
                else
                {
                    if (rate.OffPeak2Threshold == 0)
                    {
                        OffPeakCharge = rate.OffPeak1 * rate.OffPeak1Threshold + rate.OffPeak2 * (input.OffPeakUsage - rate.OffPeak1Threshold);
                    }
                    else
                    {
                        if (input.OffPeakUsage <= rate.OffPeak2Threshold)
                        {
                            OffPeakCharge = rate.OffPeak1 * rate.OffPeak1Threshold + rate.OffPeak2 * (input.OffPeakUsage - rate.OffPeak1Threshold);
                        }
                        else
                        {
                            if (rate.OffPeak3Threshold == 0)
                            {
                                OffPeakCharge = rate.OffPeak1 * rate.OffPeak1Threshold + rate.OffPeak2 * rate.OffPeak2Threshold + rate.OffPeak3 * (input.OffPeakUsage - rate.OffPeak1Threshold - rate.OffPeak2Threshold);
                            }
                            else
                            {
                                if (input.OffPeakUsage <= rate.OffPeak3Threshold)
                                {
                                    OffPeakCharge = rate.OffPeak1 * rate.OffPeak1Threshold + rate.OffPeak2 * rate.OffPeak2Threshold + rate.OffPeak3 * (input.OffPeakUsage - rate.OffPeak1Threshold - rate.OffPeak2Threshold);
                                }
                                else
                                {
                                    if (rate.OffPeak4Threshold == 0)
                                    {
                                        OffPeakCharge = rate.OffPeak1 * rate.OffPeak1Threshold + rate.OffPeak2 * rate.OffPeak2Threshold + rate.OffPeak3 * rate.OffPeak3Threshold + rate.OffPeak4 * (input.OffPeakUsage - rate.OffPeak1Threshold - rate.OffPeak2Threshold - rate.OffPeak3Threshold);
                                    }
                                    else
                                    {
                                        if (input.OffPeakUsage <= rate.OffPeak4Threshold)
                                        {
                                            OffPeakCharge = rate.OffPeak1 * rate.OffPeak1Threshold + rate.OffPeak2 * rate.OffPeak2Threshold + rate.OffPeak3 * rate.OffPeak3Threshold + rate.OffPeak4 * (input.OffPeakUsage - rate.OffPeak1Threshold - rate.OffPeak2Threshold - rate.OffPeak3Threshold);
                                        }
                                        else
                                        {
                                            OffPeakCharge = rate.OffPeak1 * rate.OffPeak1Threshold + rate.OffPeak2 * rate.OffPeak2Threshold + rate.OffPeak3 * rate.OffPeak3Threshold + rate.OffPeak4 * rate.OffPeak4Threshold + rate.OffPeak5 * (input.OffPeakUsage - rate.OffPeak1Threshold - rate.OffPeak2Threshold - rate.OffPeak3Threshold - rate.OffPeak4Threshold);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            
            Output output = new Output();
            output.PeakCharge = PeakCharge / 100;
            output.OffPeakCharge = OffPeakCharge / 100;
            output.ShoulderCharge = rate.Shoulder * input.ShoulderUsage / 100;
            output.AdditionalCharge = rate.AdditionalCharge * (input.PeakUsage + input.OffPeakUsage + input.ShoulderUsage)/100;
            output.SupplyCharge = rate.SupplyCharge * input.DaysOnBill / 31;
            output.GreenCharge = input.Green * 5.72 * (input.PeakUsage + input.OffPeakUsage + input.ShoulderUsage) / 10000;
            output.OurPrice = output.PeakCharge + output.OffPeakCharge + output.SupplyCharge + output.AdditionalCharge + output.GreenCharge;
            output.OurPricePerYear = 365 * output.OurPrice / input.DaysOnBill;
            output.SavePerBill = input.Bill - output.OurPrice;
            output.SavePerYear = 365 * output.SavePerBill / input.DaysOnBill;           
            return output;
        }

        protected RatesResult GetRates(RatesQuery query)
        {
            string table = (query.FuelType == "Electricity" ? "ElecRates" : "GasRates");
            SqlConnection connection = null;
            RatesResult result = new RatesResult();
                connection = new SqlConnection(connectionString);
                connection.Open();
                SqlCommand command;
                SqlDataReader reader;
                command = connection.CreateCommand();
                command.CommandText = "select * from " + table + " where State='" + query.State + "' and PlanType='" + query.PlanType + "' and Provider='" + query.Provider + "' and RatesApply='" + query.RatesApply + "' and OrgType='" + query.OrgType + "';";
                reader = command.ExecuteReader();
                reader.Read();
                result.Peak1 = (reader["Peak1"] is DBNull ? 0 : Convert.ToDouble(reader["Peak1"]));
                result.Peak1Threshold = (reader["Peak1Threshold"] is DBNull ? 0 : Convert.ToDouble(reader["Peak1Threshold"]));
                result.Peak2 = (reader["Peak2"] is DBNull ? 0 : Convert.ToDouble(reader["Peak2"]));
                result.Peak2Threshold = (reader["Peak2Threshold"] is DBNull ? 0 : Convert.ToDouble(reader["Peak2Threshold"]));
                result.Peak3 = (reader["Peak3"] is DBNull ? 0 : Convert.ToDouble(reader["Peak3"]));
                result.Peak3Threshold = (reader["Peak3Threshold"] is DBNull ? 0 : Convert.ToDouble(reader["Peak3Threshold"]));
                result.Peak4 = (reader["Peak4"] is DBNull ? 0 : Convert.ToDouble(reader["Peak4"]));
                result.Peak4Threshold = (reader["Peak4Threshold"] is DBNull ? 0 : Convert.ToDouble(reader["Peak4Threshold"]));
                result.Peak5 = (reader["Peak5"] is DBNull ? 0 : Convert.ToDouble(reader["Peak5"]));
                result.OffPeak1 = (reader["OffPeak1"] is DBNull ? 0 : Convert.ToDouble(reader["OffPeak1"]));
                result.OffPeak1Threshold = (reader["OffPeak1Threshold"] is DBNull ? 0 : Convert.ToDouble(reader["OffPeak1Threshold"]));
                result.OffPeak2 = (reader["OffPeak2"] is DBNull ? 0 : Convert.ToDouble(reader["OffPeak2"]));
                result.OffPeak2Threshold = (reader["OffPeak2Threshold"] is DBNull ? 0 : Convert.ToDouble(reader["OffPeak2Threshold"]));
                result.OffPeak3 = (reader["OffPeak3"] is DBNull ? 0 : Convert.ToDouble(reader["OffPeak3"]));
                result.OffPeak3Threshold = (reader["OffPeak3Threshold"] is DBNull ? 0 : Convert.ToDouble(reader["OffPeak3Threshold"]));
                result.OffPeak4 = (reader["OffPeak4"] is DBNull ? 0 : Convert.ToDouble(reader["OffPeak4"]));
                result.OffPeak4Threshold = (reader["OffPeak4Threshold"] is DBNull ? 0 : Convert.ToDouble(reader["OffPeak4Threshold"]));
                result.OffPeak5 = (reader["OffPeak5"] is DBNull ? 0 : Convert.ToDouble(reader["OffPeak5"]));
                result.Shoulder = (reader["Shoulder"] is DBNull ? 0:Convert.ToDouble(reader["Shoulder"]));
                result.SupplyCharge = (reader["SupplyCharge"] is DBNull ? 0:Convert.ToDouble(reader["SupplyCharge"]));
                result.AdditionalCharge = (reader["AdditionalCharge"] is DBNull ? 0 : Convert.ToDouble(reader["AdditionalCharge"]));
                result.Code = (reader["Code"] is DBNull ? "":Convert.ToString(reader["Code"]));
                result.Tariff = (reader["Tariff"] is DBNull ? "":Convert.ToString(reader["Tariff"]));
                reader.Close();
                connection.Close();
            return result;
        }

        protected DiscountResult GetDiscount(string PostCode)
        {
            SqlConnection connection = null;
            DiscountResult result = new DiscountResult();
                connection = new SqlConnection(connectionString);
                connection.Open();
                SqlCommand command;
                SqlDataReader reader;
                command = connection.CreateCommand();
                command.CommandText = "select * from Discount where PostCode='" + PostCode + "';";
                reader = command.ExecuteReader();
                reader.Read();
                result.State = Convert.ToString(reader["state"]);
                result.ElectricityZone = Convert.ToString(reader["ElectricityZone"]);
                result.PreGST_Discount_RESI = Convert.ToDouble(reader["PreGST_Discount_RESI"]);
                result.PostGST_Discount_RESI = Convert.ToDouble(reader["PostGST_Discount_RESI"]);
                result.Rebate_RESI = Convert.ToString(reader["Rebate_RESI"]);
                result.ProductCode_RESI = Convert.ToString(reader["ProductCode_RESI"]);
                result.PreGST_Discount_SME = Convert.ToDouble(reader["PreGST_Discount_SME"]);
                result.PostGST_Discount_SME = Convert.ToDouble(reader["PostGST_Discount_SME"]);
                result.Rebate_SME = Convert.ToString(reader["Rebate_SME"]);
                result.ProductCode_SME = Convert.ToString(reader["ProductCode_SME"]);
                reader.Close();
                connection.Close();
            return result;
        }

        protected string GetGasZone(string PostCode)
        {
            SqlConnection connection = null;
            string result;
                connection = new SqlConnection(connectionString);
                connection.Open();
                SqlCommand command;
                SqlDataReader reader;
                command = connection.CreateCommand();
                command.CommandText = "select * from GasZone where PostCode='" + PostCode + "';";
                reader = command.ExecuteReader();
                reader.Read();
                result = reader["GasZone"]is DBNull ? "" : Convert.ToString(reader["GasZone"]);
                reader.Close();
                connection.Close();
            return result;
        }

        protected double post_pre_GST(double post_rate)
        {
            double pre_rate;
            pre_rate = post_rate * 10 / 11;
            return pre_rate;
        }

        protected double pre_post_GST(double pre_rate)
        {
            double post_rate;
            post_rate = pre_rate * 11 / 10;
            return post_rate;
        }

        protected double discount(double dis, double pre_rate)
        {
            double post_rate;
            post_rate = pre_rate*(1 - dis);
            return post_rate;
        }

        protected double discalcu(double pre_dis, double post_dis, double post_rate)
        {
            double pre_rates = post_pre_GST(post_rate);
            double pre_dis_rate = discount(pre_dis, pre_rates);
            double post_dis_rate = pre_post_GST(pre_dis_rate);
            double new_rates = discount(post_dis, post_dis_rate);
            return new_rates;
        }

        private void MessageBox(string message)
        {
            if (!string.IsNullOrEmpty(message))
            {
                this.ClientScript.RegisterClientScriptBlock(this.GetType(), "alt1", "alert('" + message + "');", true);
            }
        }




    }
}